#include "MainWindow.h"
#include <QApplication>

#include <QDir>
#include <QString>
#include <QDateTime>
#include <QFile>
#include <QDate>
#include <QMutex>
#include <QThread>
#include <QTextStream>
#include <QDebug>
#include <QTranslator>

#include "SingleApplication/QtSingleApplication.h"
#include "MachineHelper.h"

#define LOG_RECORD_MAX_DAY 7
#define LOG_RECORD_PATH (QDir::tempPath() + "/VVClassUpdate-LogRecord")

class LogRecordHelper
{
public:
    static LogRecordHelper *getLogRecordHelper();
    void deleteLogFile();

private:
    LogRecordHelper();

private:
    static LogRecordHelper *mLogRecordHelper;
};


LogRecordHelper::LogRecordHelper()
{

}

LogRecordHelper *LogRecordHelper::mLogRecordHelper = NULL;

LogRecordHelper* LogRecordHelper::getLogRecordHelper()
{
    if(mLogRecordHelper){
        mLogRecordHelper = new LogRecordHelper();
    }
    return mLogRecordHelper;
}

//删除超过一个月的日志
void LogRecordHelper::deleteLogFile()
{
    QDir dir(LOG_RECORD_PATH);
    if(dir.exists()){
        dir.setFilter(QDir::Files | QDir::NoSymLinks);
        QFileInfoList list = dir.entryInfoList();
        foreach(QFileInfo fileInfo,list){
            QString fileName = fileInfo.fileName();
            if(fileName.contains("logRecord-")){
                fileName.replace("logRecord-","");
                fileName.replace(".log","");
                QDate fileDate = QDate::fromString(fileName,"yyyy-MM-dd");
                QDate currentDate = QDate::currentDate();
                if(fileDate.addDays(LOG_RECORD_MAX_DAY) < currentDate){
                    QFile::remove(fileInfo.absoluteFilePath());
                }
            }else{
                QFile::remove(fileInfo.absoluteFilePath());
            }
        }
    }
}


#define _TIME_ qPrintable(QDateTime::currentDateTime().toString( \
    "yyyy-MM-dd hh:mm:ss:zzz"))

void myMessageOutput(QtMsgType                 type,
                     const QMessageLogContext& context,
                     const QString           & msg)
{
    QString qstrText;
    static QMutex mutex;
    QString fileName = context.file;
    if(fileName.endsWith("\\")){
        fileName.remove(fileName.length()-1,1);
    }
    fileName = fileName.mid(fileName.lastIndexOf("\\")+1);

    switch (type) {
    case QtDebugMsg:
        qstrText =
                QString("[%1] [Debug] [%2:%3] [%4]").arg(_TIME_).arg(fileName).arg(context.line).arg(context.function);
        break;
    case QtWarningMsg:
        qstrText =
                QString("[%1] [Warning] [%2:%3] [%4] ").arg(_TIME_).arg(fileName).arg(context.line).arg(context.function);
        break;
    case QtCriticalMsg:
        qstrText =
                QString("[%1] [Critical] [%2:%3] [%4]").arg(_TIME_).arg(fileName).arg(context.line).arg(context.function);
        break;
    case QtFatalMsg:
        qstrText =
                QString("[%1] [Fatal] [%2:%3] [%4]").arg(_TIME_).arg(fileName).arg(context.line).arg(context.function);
    default:
        return;
    }

    QFile out(LOG_RECORD_PATH + "/logRecord-" + QDateTime::currentDateTime().toString("yyyy-MM-dd") + ".log");

    mutex.lock();
    if (out.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
        //        if(out.size() >= 1024*1024*64){
        //            out.close();
        //            out.open(QIODevice::WriteOnly | QIODevice::Text);
        //        }
        QTextStream ts(&out);
        ts << qstrText << "  [" << QThread::currentThreadId() << "]  [" << msg << "]" << endl;
        out.close();
    }
    mutex.unlock();
}

void init_syslog(int logLevel)
{
    QDir dir;
    if (!dir.exists(LOG_RECORD_PATH)) {
        dir.mkdir(LOG_RECORD_PATH);
    }

    //删除多余日志文件
    LogRecordHelper::getLogRecordHelper()->deleteLogFile();
    if(logLevel >= 0) {
        qInstallMessageHandler(myMessageOutput);
    }

}

int main(int argc, char *argv[])
{
    QtSingleApplication *app = new QtSingleApplication(argc, argv);

    if(app->isRunning()) {
        app->sendMessage(QLatin1String("AlreadyExisted"));
        qWarning() << "VVClassUpdate already startup!";
        delete app;
        return -1;
    }
    app->setApplicationName(QLatin1String("VVClassUpdate"));

    QTranslator *translator = new QTranslator(app);
    translator->load(":/VVClassUpdate_zh_CN.qm");
    app->installTranslator(translator);

    init_syslog(QtDebugMsg);

    //无任何类型网卡时
    if(!MachineHelper::GetInstance()->getNetInterfaceOnlineStatus()){
        QEventLoop loop;
        QObject::connect(MachineHelper::GetInstance(),&MachineHelper::sigNetOnlineStatusChanged,&loop,[&loop](bool isOnline){
            qDebug() << "The network is connected, exit getNetInterfaceOnlineStatus for event loop: " << isOnline;
            if(isOnline){
                loop.quit();
            }
        });
        loop.exec();
    } else {
        qDebug() << "network normal";
    }
    qDebug() << "get networkstate: " << MachineHelper::GetInstance()->getNetInterfaceOnlineStatus();

    QString downloadUrl;
    QString forceUpdate;
    QString externalNetworkFlag;
    QString quictunPort;
    QString serverAppAddr;
    QString titleContext;
    if(argc >= 4 ) {
        downloadUrl = argv[1];
        forceUpdate = argv[2];
        titleContext = argv[3];
    }

#ifdef TEST_DOWNLOAD
    // 文件下载测试地址
    // https://dldir1v6.qq.com/weixin/Universal/Windows/WeChatWin.exe
    // https://dldir1v6.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.20_250724_x64_01.exe
    // https://vscode.download.prss.microsoft.com/dbazure/download/stable/360a4e4fd251bfce169a4ddf857c7d25d1ad40da/VSCodeUserSetup-x64-1.103.1.exe
    // https://www.scootersoftware.com/files/BCompare-zh-5.0.1.29877.exe
    QString fiileUrl = "https://www.scootersoftware.com/files/BCompare-zh-5.0.1.29877.exe";

    downloadUrl = fiileUrl;
    forceUpdate = "0";
    titleContext = "VVClass";
#endif

    if (argc >= 7) {
        externalNetworkFlag = argv[4];
        quictunPort = argv[5];
        serverAppAddr = argv[6];
    }

    qDebug() << "-------downloadUrl:" << downloadUrl <<"-------forceUpdate:"<<forceUpdate <<"---------------externalNetworkFlag"<<externalNetworkFlag
             <<"-----------quictunPort"<<quictunPort<<"-----------serverAppAddr"<<serverAppAddr;

    if (downloadUrl.isEmpty())
        return -1;
    bool force = (bool)forceUpdate.toInt();
    bool Flag = (bool)externalNetworkFlag.toInt();

    MainWindow w(downloadUrl,force,titleContext,Flag,quictunPort,serverAppAddr);
    w.show();
    return app->exec();
}

